from typing import List

from Token import *
from utils import is_number, is_boolean_true, is_boolean_false, is_null



# Token = Dict[str, str]

def tokenizer(input: str) -> List[Token]:
    """Tokenize the input string into a list of tokens."""
    current = 0
    tokens: List[Token] = []

    while current < len(input):
        # print("[debug] now tokens[] is", tokens)
        # print("\n")
        char = input[current]

        if char == "{":
            # tokens.append({"type": "BraceOpen", "value": char})
            tokens.append( Token(token_type=TokenType.BRACE_OPEN, value=char) )
            current += 1
            continue

        if char == "}":
            # tokens.append({"type": "BraceClose", "value": char})
            tokens.append( Token(token_type=TokenType.BRACE_CLOSE, value=char) )
            current += 1
            continue

        if char == "[":
            # tokens.append({"type": "BracketOpen", "value": char})
            tokens.append( Token(token_type=TokenType.BRACKET_OPEN, value=char) )
            current += 1
            continue

        if char == "]":
            # tokens.append({"type": "BracketClose", "value": char})
            tokens.append( Token(token_type=TokenType.BRACKET_CLOSE, value=char) )
            current += 1
            continue

        if char == ":":
            # tokens.append({"type": "Colon", "value": char})
            tokens.append( Token(token_type=TokenType.COLON, value=char) )
            current += 1
            continue

        if char == ",":
            # tokens.append({"type": "Comma", "value": char})
            tokens.append( Token(token_type=TokenType.COMMA, value=char) )
            current += 1
            continue

        if char == '"':
            value = ""
            current += 1
            char = input[current]
            while char != '"':
                value += char
                current += 1
                char = input[current]
            current += 1
            # tokens.append({"type": "String", "value": value})
            tokens.append( Token(token_type=TokenType.STRING, value=value) )
            continue

        # For number, boolean, and null values
        if char.isalnum() or char in "-.":  # Including '-' and '.' for negative numbers and decimals
            value = ""
            while ( char.isalnum() or char in "-." ):
                value += char
                current += 1
                char = input[current]
            # while current < len(input) and (input[current].isalnum() or input[current] in "-."):
            #     value += input[current]
            #     current += 1

            if is_number(value):
                # tokens.append({"type": "Number", "value": value})
                tokens.append( Token(token_type=TokenType.NUMBER, value=value) )
            elif is_boolean_true(value):
                # tokens.append({"type": "True", "value": value})
                tokens.append( Token(token_type=TokenType.TRUE, value=value) )
            elif is_boolean_false(value):
                # tokens.append({"type": "False", "value": value})
                tokens.append( Token(token_type=TokenType.FALSE, value=value) )
            elif is_null(value):
                # tokens.append({"type": "Null", "value": value})
                tokens.append( Token(token_type=TokenType.NULL, value=value) )
            else:
                raise ValueError(f"Unexpected value: {value}")

            continue

        # Skip whitespace
        if char.isspace():
            current += 1
            continue

        raise ValueError(f"Unexpected character: {char}")

    print("[debug] before return, now tokens[] is", tokens)
    print("\n")
    return tokens
